﻿using System.Collections.Generic;

namespace BorgExt
{
    [Slot("Borg.Analyzer"), Plug("Discoverer"), Extension]
    public class BootstrapDiscoverer : ExtensionBase, IDiscoverer
    {
        public event DiscoveryEventHandler Changed;
        public event DiscoveryEventHandler Discovered;
        public event DiscoveryEventHandler Removed;

        public void Dispose()
        { }

        protected void OnChanged(ICollection<Contract> contracts, ICollection<Plugin> plugins)
        {
            if (Changed != null)
                Changed(new DiscoveryEventArgs(contracts, plugins));
        }

        protected void OnDiscovered(ICollection<Contract> contracts, ICollection<Plugin> plugins)
        {
            if (Discovered != null)
                Discovered(new DiscoveryEventArgs(contracts, plugins));
        }

        protected void OnRemoved(ICollection<Contract> contracts, ICollection<Plugin> plugins)
        {
            if (Removed != null)
                Removed(new DiscoveryEventArgs(contracts, plugins));
        }

        public void Start(TypeBuilder typeBuilder)
        {
            if (BootstrapPaths == null)
                return;

            var contracts = new List<Contract>();
            var plugins = new List<Plugin>();
            var slot = Slots["Borg.Analyzer"];

            foreach (var paths in BootstrapPaths)
            {
                foreach (var plug in slot.PluggedPlugs)
                {
                    ICollection<Contract> contractColl;
                    ICollection<Plugin> pluginColl;

                    ((IAnalyzer)plug.Extension.Object).
                        Analyze(paths, typeBuilder, out contractColl, out pluginColl);

                    if (contractColl != null)
                        contracts.AddRange(contractColl);

                    if (pluginColl != null)
                        plugins.AddRange(pluginColl);
                }
            }

            OnDiscovered(contracts, plugins);
            Runtime.Composer.InvokeOnCompositionDone(UnplugDiscoverer);
        }

        private void UnplugDiscoverer()
        {
            var plug = Plugs["Discoverer"];

            foreach (var slot in plug.SlotsWherePlugged)
                slot.Unplug(plug);
        }

        public string[] BootstrapPaths { get; set; }
    }
}

